package com.migration.service.impl;

import com.migration.model.newdb.RiskChainEffect;
import com.migration.model.newdb.RiskChainEffectChemical;
import com.migration.model.newdb.RiskChainEffectDeviation;
import com.migration.model.newdb.RiskChainEffectNextDevice;
import com.migration.model.olddb.*;
import com.migration.service.RiskChainEffectService;
import com.migration.util.CommonUtils;
import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 事故链-影响表服务实现类
 */
@Service
public class RiskChainEffectServiceImpl implements RiskChainEffectService {

    @Override
    public List<RiskChainEffect> migrateEffectData(
            EntityManager oldEntityManager,
            EntityManager newEntityManager,
            Map<Long, RaInfluence> influenceMap,
            Map<Long, Set<Long>> sourceIdToInfluenceIds,
            List<RaFaultChainsDetail> detailList,
            Map<Long, RaDeviateReason> reasonMap) {

        Set<Long> processedInfluenceIds = new HashSet<>();
        List<RiskChainEffect> effectList = new ArrayList<>();

        // 第一步：预处理数据，收集不同的parent_id和reason_id组合
        Map<String, List<RaFaultChainsDetail>> groupedDetails = new HashMap<>();

        // 按照parent_id和reason_id分组
        for (RaFaultChainsDetail detail : detailList) {
            if (detail.getParentId() != null && detail.getReasonId() != null) {
                String groupKey = detail.getParentId() + "_" + detail.getReasonId();
                if (!groupedDetails.containsKey(groupKey)) {
                    groupedDetails.put(groupKey, new ArrayList<>());
                }
                groupedDetails.get(groupKey).add(detail);
            }
        }

        // 第二步：对每个组内的数据按照parent_path排序，并分配序列号
        Map<Long, Integer> detailIdToSerialNum = new HashMap<>();

        for (List<RaFaultChainsDetail> group : groupedDetails.values()) {
            // 按照parent_path排序
            group.sort(Comparator.comparing(
                    detail -> detail.getParentPath() == null ? "" : detail.getParentPath()
            ));

            // 分配序列号
            for (int i = 0; i < group.size(); i++) {
                detailIdToSerialNum.put(group.get(i).getId(), i + 1); // 序列号从1开始
            }
        }

        for (Long sourceId : sourceIdToInfluenceIds.keySet()) {
            if (influenceMap.containsKey(sourceId)) {
                RaInfluence influence = influenceMap.get(sourceId);

                if (processedInfluenceIds.contains(influence.getId())) {
                    continue; // 跳过已处理的影响节点
                }

                // 查找该影响节点对应的事故链详情
                for (RaFaultChainsDetail detail : detailList) {
                    if (detail.getInfluenceId() != null && detail.getInfluenceId().equals(influence.getId())) {
                        RiskChainEffect effect = new RiskChainEffect();

                        // 设置基础属性
                        effect.setId(detail.getId());
                        effect.setEffectId(detail.getId() + "");
                        effect.setTenantId(1L);
                        effect.setDepartmentId(influence.getTenantId().longValue()); // 部门

                        // 设置分析类型
                        effect.setAnalysisType(detail.getFaultChainsType() != null ? detail.getFaultChainsType().intValue() : 1);

                        // 设置原因ID
                        Long reasonId = detail.getReasonId();
                        if (reasonId != null) {
                            effect.setCauseId(reasonId.toString());

                            // 从reasonMap中获取analysisId
                            RaDeviateReason reason = reasonMap.get(reasonId);
                            if (reason != null && reason.getLinkedId() != null) {
                                effect.setAnalysisId(reason.getLinkedId());
                            } else {
                                continue; // 没有原因ID，跳过
                            }
                        } else {
                            continue; // 没有原因ID，跳过
                        }

                        // 设置父节点ID
                        effect.setParentEffectId(detail.getParentId() != null && detail.getParentId() != 0L ?
                                detail.getParentId().toString() : "0");

                        // 设置来源影响节点ID
                        // TODO: 暂时写自己，找不到
//                        effect.setFromEffectId(influence.getId().toString());
                        effect.setFromEffectId(detail.getId() + "");

                        // 设置序号 - 从映射中获取序列号
                        Integer serialNum = detailIdToSerialNum.get(detail.getId());
                        effect.setSerialNum(serialNum != null ? serialNum : 0);


                        // 设置设备ID
                        effect.setDeviceId(influence.getCurrentNodeId() != null ? influence.getCurrentNodeId() : 0L);

                        // 设置描述信息
                        effect.setEffectDesc(influence.getInfluenceDesc() != null ? influence.getInfluenceDesc() : "");
                        effect.setNodeRemark(detail.getRemark());

                        // 设置时间和创建人信息
                        effect.setCreateTime(CommonUtils.formatDateTime(influence.getCreateTime()));
                        effect.setUpdateTime(CommonUtils.formatDateTime(influence.getCreateTime()));
                        effect.setCreateBy(1L);
                        effect.setUpdateBy(1L);
                        effect.setIsDel(false);

                        effectList.add(effect);
                        newEntityManager.persist(effect);

                        processedInfluenceIds.add(influence.getId());
                    }
                }
            }
        }

        return effectList;
    }

    @Override
    public List<RaInfluence> getAllInfluences(EntityManager oldEntityManager) {
        CriteriaBuilder oldCriteriaBuilder = oldEntityManager.getCriteriaBuilder();
        CriteriaQuery<RaInfluence> influenceQuery = oldCriteriaBuilder.createQuery(RaInfluence.class);
        Root<RaInfluence> influenceRoot = influenceQuery.from(RaInfluence.class);
        influenceQuery.select(influenceRoot);
        influenceQuery.where(oldCriteriaBuilder.equal(influenceRoot.get("isDel"), (byte) 0));
        return oldEntityManager.createQuery(influenceQuery).getResultList();
    }

    @Override
    public Map<Long, RaInfluence> buildInfluenceMap(List<RaInfluence> influenceList) {
        return influenceList.stream()
                .collect(java.util.stream.Collectors.toMap(RaInfluence::getId, influence -> influence, (a, b) -> a));
    }

    @Override
    public Map<Long, Set<Long>> buildSourceIdToInfluenceIdsMap(
            List<RaFaultChainsMeasure> measureList,
            List<RaFaultChainsDetail> detailList) {

        Map<Long, Set<Long>> sourceIdToInfluenceIds = new HashMap<>();

        // 处理措施关系，获取影响节点
        for (RaFaultChainsMeasure measure : measureList) {
            Long sourceId = measure.getSourceId();
            Byte sourceType = measure.getSourceType();

            if (sourceType != null && sourceType == 1) {
                // 影响节点
                sourceIdToInfluenceIds.computeIfAbsent(sourceId, k -> new HashSet<>()).add(sourceId);
            }
        }

        // 处理事故链详情，关联影响节点
        for (RaFaultChainsDetail detail : detailList) {
            Long influenceId = detail.getInfluenceId();
            Long reasonId = detail.getReasonId();

            if (influenceId != null && reasonId != null) {
                sourceIdToInfluenceIds.computeIfAbsent(influenceId, k -> new HashSet<>()).add(influenceId);
            }
        }

        return sourceIdToInfluenceIds;
    }

    @Override
    public List<RaInfluenceLinked> getAllInfluenceLinked(EntityManager oldEntityManager) {
        CriteriaBuilder oldCriteriaBuilder = oldEntityManager.getCriteriaBuilder();
        CriteriaQuery<RaInfluenceLinked> influenceLinkedQuery = oldCriteriaBuilder.createQuery(RaInfluenceLinked.class);
        Root<RaInfluenceLinked> influenceLinkedRoot = influenceLinkedQuery.from(RaInfluenceLinked.class);
        influenceLinkedQuery.select(influenceLinkedRoot);
        return oldEntityManager.createQuery(influenceLinkedQuery).getResultList();
    }

    @Override
    public int migrateEffectRelationData(
            EntityManager oldEntityManager,
            EntityManager newEntityManager,
            List<RiskChainEffect> effectList,
            List<RaInfluenceLinked> influenceLinkedList) {

        // 创建一个映射表用于查找影响节点ID对应的影响详情ID(RiskChainEffect.effectId)
        Map<Long, String> influenceIdToEffectIdMap = new HashMap<>();
        for (RiskChainEffect effect : effectList) {
            // 注意：这里的id是从detail.getId()获取的，它与influenceId相对应
            influenceIdToEffectIdMap.put(effect.getId(), effect.getEffectId());
        }

        int rowCount = 0; // 记录关联数据处理行数

        // 处理所有关联数据
        for (RaInfluenceLinked linked : influenceLinkedList) {
            if (linked.getLinkedType() == null || linked.getInfluenceId() == null) {
                continue;
            }

            Long influenceId = linked.getInfluenceId();
            String effectId = influenceIdToEffectIdMap.get(influenceId);

            if (effectId == null) {
                continue; // 找不到对应的影响详情ID，跳过
            }

            // 根据关联类型分别处理
            if (linked.getLinkedType() == 1) {
                // 偏离关联
                RiskChainEffectDeviation deviation = new RiskChainEffectDeviation();
                deviation.setId(linked.getId());
                deviation.setEffectId(effectId);
                deviation.setDeviationId(linked.getLinkedId());
                newEntityManager.persist(deviation);
                rowCount++; // 增加计数
            } else if (linked.getLinkedType() == 2) {
                // 化学品关联
                RiskChainEffectChemical chemical = new RiskChainEffectChemical();
                chemical.setId(linked.getId());
                chemical.setEffectId(effectId);
                chemical.setChemicalId(linked.getLinkedId());
                newEntityManager.persist(chemical);
                rowCount++; // 增加计数
            } else if (linked.getLinkedType() == 3) {
                // 下一节点设备关联
                RiskChainEffectNextDevice nextDevice = new RiskChainEffectNextDevice();
                nextDevice.setId(linked.getId());
                nextDevice.setEffectId(effectId);
                nextDevice.setNextDeviceId(linked.getLinkedId());
                newEntityManager.persist(nextDevice);
                rowCount++; // 增加计数
            }
        }

        return rowCount; // 返回处理的行数
    }
}
